#define _CRT_SECURE_NO_WARNINGS
#include <string>
//#include <stdio.h>
#include "myString.h"

// �����������
MyString::MyString(const char* Str)
{
	if (Str)
	{
		m_pCounter = Counter::CreateCounter(Str);
		m_pCounter->AddOwner();
	}
	else{ m_pCounter = nullptr;	} //������� �� ������� ����������
}

//����������� �����������
MyString::MyString(const MyString& Other)
{
	m_pCounter = Other.m_pCounter;
	
	if (m_pCounter)
	{		
		m_pCounter->AddOwner();
	}	
}

//������������ ����������� �����������
MyString::MyString(MyString&& Other)
{
	m_pCounter = Other.m_pCounter; //������ �������� ������
	Other.m_pCounter = nullptr;//�������, ��� � ������� ��� 
}

// �����������
MyString::~MyString()
{
	if (m_pCounter)	{ m_pCounter->RemoveOwner(); }	
}

//����� , ������� ��������� ������ � ���������� ������
const char* MyString::GetString() const
{
	if (m_pCounter) { return m_pCounter->m_pStr; }
}

//�����, ������� ����� �������� ������ �� �����
void MyString::SetNewString(const char* Str) 
{
	if (Str)//��������� �� ������ �� �������
	{
		if (m_pCounter) 
		{m_pCounter->RemoveOwner();}//������ ������� ��������
		
		m_pCounter = Counter::CreateCounter(Str);//�������� ����������� ������������ ��������
		m_pCounter->AddOwner(); //����������� ����������		
	}
	else { m_pCounter = nullptr; }
}

//�������� ������������
MyString& MyString::operator=(const MyString& Other)
{
	if (&Other != this)
	{
		if (m_pCounter != Other.m_pCounter)
		{
			if (m_pCounter) { m_pCounter->RemoveOwner(); }
			
			m_pCounter = Other.m_pCounter;
			
			if (Other.m_pCounter) { m_pCounter->AddOwner(); }
		}
	}
	
	return *this;
}

//������������ �������� ������������
MyString& MyString::operator=(MyString&& Other)
{
	if (&Other != this)
	{
		if (m_pCounter != Other.m_pCounter)
		{
			if (m_pCounter) { m_pCounter->RemoveOwner(); }
			m_pCounter = Other.m_pCounter;
			Other.m_pCounter = nullptr;
		}
	}
	return *this;	
}

void MyString::PrintAllStrings()
{
	Counter* pCounter = Counter::Head;
	for (size_t i = 0; i < Counter::m_curCounters; i++)
	{
		std::cout << pCounter->m_pStr << "\n";
		pCounter = pCounter->pNext;
	}
}

void MyString::ChangeRegister()
{
	Counter* pCounter = Counter::Head;
	bool fl = false;
	
	for (size_t i = 0; i < Counter::m_curCounters; i++)
	{
		for (size_t i = 0; i < strlen(pCounter->m_pStr); i++)
		{
			if (pCounter->m_pStr[i]>=65 && pCounter->m_pStr[i] <= 90)
			{
				pCounter->m_pStr[i] += 32;
				fl = true;
			}

			if (pCounter->m_pStr[i] >= 97 && pCounter->m_pStr[i] <= 122 && !fl)
			{
				pCounter->m_pStr[i] -= 32;
			}
			fl = false;
		}

		pCounter = pCounter->pNext;
	}
}

//	<0, ���� str1 < str2
//	= 0, ���� str1 = str2
//	>0, ���� str1 > str2

void MyString::PrintSortedStrings()
//�� �����������
{
	if (Counter::m_curCounters <= 1) { return; }

	Counter* start_Str = Counter::Head;//������ ��������� �� ��������� Counter (������� ����)
	Counter* current = start_Str;//������ ��������� �� ������� Counter (���������� ����)
	Counter* min_Counter = current;//������ ��������� �� ����������� ������

	for (size_t i = 0; i < Counter::m_curCounters; i++)
	{				
		const char* min_Str = current->m_pStr;

		bool fl = false;

		for (size_t j = i+1; j < Counter::m_curCounters; j++)
		{
			current = current->pNext;

			if (strcmp(min_Str, current->m_pStr) > 0)
			{
				min_Str = current->m_pStr;
				min_Counter = current;
				fl = true;
			}			
		}

		if (fl)
		{
			(*start_Str).Swap(min_Counter);
			current = min_Counter;
			current=start_Str = min_Counter->pNext;
			continue;
		}

		current = start_Str = start_Str->pNext;
		min_Counter = current;
	}

	PrintAllStrings();
}


std::ostream& operator<<(std::ostream& os, const MyString& str)
{
	os << str.m_pCounter->m_pStr;
	return os;
}
